#!/usr/bin/perl -w 
# 20 CUDA benchmarks, Inti
# 13 rodinia benchmarks, Titan
# 7  parboil benchmarks, Inti
# 40 benchmarks in total

# (X >= 6) are long running

use English;

@cuda = ("AES", "BFS", "BLK", "CP", "JPEG", "LIB", "LPS", "MUM", "NN", "NQU", "RAY", "STO", "WP", "DN", "SCP", "TRA", "FWT", "SLA", "CON");

@rodinia = ("BP", "BFSR", "HS", "NW", "LUD", "LYTE", "PFF", "PFN", "SD1", "SD2");

@parboil = ("CUTP", "FFT", "MM", "SAD", "SPMV");

@long_running = ("KMEANS", "CFD", "HW", "SC", "LBM", "TPCAF");

@cuda_list = ("CUDA/AES/output_AES.txt", 
"CUDA/BFS/output_BFS.txt", "CUDA/BlackScholes/output_BlackScholes.txt", "CUDA/CP/output_CP.txt","CUDA/JPEG/output_JPEG.txt", "CUDA/LIB/output_LIB.txt",
"CUDA/LPS/output_LPS.txt", "CUDA/MUM/output_MUM.txt", "CUDA/NN/output_NN.txt", "CUDA/NQU/output_NQU.txt", "CUDA/RAY/output_RAY.txt", "CUDA/STO/output_STO.txt", "CUDA/WP/output_WP.txt", "CUDA/denoise/output_denoise.txt", "CUDA/SCP/output_SCP.txt", "CUDA/TRA/output_TRA.txt", "CUDA/FWT/output_FWT.txt", "CUDA/SLA/output_SLA.txt", "CUDA/CON/output_CON.txt");

@rodinia_list = ("rodinia/backprop/output_backprop.txt", "rodinia/bfs/output_bfs.txt", "rodinia/hotspot/output_hotspot.txt", 
"rodinia/nw/output_nw.txt", "rodinia/lud/output_lud.txt", "rodinia/leukocyte/output_leukocyte.txt", "rodinia/pf_float/output_pf_float.txt", 
"rodinia/pf_naive/output_pf_naive.txt", "rodinia/srad_v1/output_srad_v1.txt", "rodinia/srad_v2/output_srad_v2.txt");

@parboil_list = ("parboil/cutcp/output_cutcp.txt", "parboil/fft/output_fft.txt", 
"parboil/mm/output_mm.txt", "parboil/sad/output_sad.txt", "parboil/spmv/output_spmv.txt");

@long_running_list = ("CUDA/kmeans/output_kmeans.txt", "rodinia/cfd/output_cfd.txt", "rodinia/heartwall/output_heartwall.txt", 
"rodinia/streamcluster/output_streamcluster.txt", "parboil/lbm/output_lbm.txt", "parboil/tpacf/output_tpacf.txt");

print "$ARGV[0]\n";

$bench = $ARGV[0];

if ($bench eq "CUDA") {
@file_list = @cuda_list;
@benchmarks = @cuda;
$result_file = "CUDA_results.txt";
}

if ($bench eq "rodinia") {
@file_list = @rodinia_list;
@benchmarks = @rodinia;
$result_file = "rodinia_results.txt";
}

if ($bench eq "parboil") {
@file_list = @parboil_list;
@benchmarks = @parboil;
$result_file = "parboil_results.txt";
}

if ($bench eq "long") {
@file_list = @long_running_list;
@benchmarks = @long_running;
$result_file = "long_results.txt";
}


if ($bench eq "ALL") {
@file_list = (@cuda_list, @rodinia_list, @parboil_list, @long_running_list);
@benchmarks = (@cuda, @rodinia, @parboil, @long_running);
$result_file = "all_results.txt";
}


open(OUTPUT, ">$result_file") || die "Cannot open file $result_file for writing\n";

for ($j = 0; $j <= $#file_list; $j++) {  
		
	my $ins = `grep gpu_tot_sim_insn $file_list[$j] | tail -n 1 | awk '\{print \$3\}'`;
	chomp($ins);
	push @globalins, $ins;	
	
	my $Stall = `grep "Stall" $file_list[$j] | tail -n 1 |  awk -F ':' '\{print \$2\}' |  awk '\{print \$1\}'`;
	chomp($Stall);
	push @globalStall, $Stall;
	
	my $W0Idle= `grep "Stall" $file_list[$j] | tail -n 1 |  awk -F ':' '\{print \$3\}' |  awk '\{print \$1\}'`;
	chomp($W0Idle);
	push @globalW0Idle, $W0Idle;
	
	my $W0Mem = `grep "Stall" $file_list[$j] | tail -n 1 |  awk -F ':' '\{print \$4\}' |  awk '\{print \$1\}'`;
	chomp($W0Mem);
	push @globalW0Mem, $W0Mem;

    my $total_dram_queue = `grep "DRAM_QUEUE_TIME" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($total_dram_queue);
    push @globaltotal_dram_queue, $total_dram_queue;
	
	my $total_dram_spent = `grep "DRAM_SPENT_TIME" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($total_dram_spent);
    push @globaltotal_dram_spent, $total_dram_spent;
	
	my $averagemflatency = `grep "averagemflatency" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($averagemflatency);
    push @globalaveragemflatency, $averagemflatency;	
	
    my $latency1 = `grep "average latency" $file_list[$j] | tail -n 2| head -n 1| awk '\{print \$5\}'`;
    chomp($latency1);
    push @globallatency1, $latency1;

	my $latency2 = `grep "average latency" $file_list[$j] | tail -n 1| awk '\{print \$5\}'`;
    chomp($latency2);
    push @globallatency2, $latency2;
		
	my $kernels = `grep "stats for grid" $file_list[$j] | tail -n 1| awk '\{print substr(\$0\,length-1)}'`;
	chomp($kernels);
    push @globalkernels, ($kernels + 1);
	
	@MAX_WARPS = `grep "MAX_WARPS" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@MAX_WARPS);
	push @globalMAX_WARPS, [avg(\@MAX_WARPS)];

	@CTAS_PER_ROW = `grep "CTAS_PER_ROW" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@CTAS_PER_ROW);
	push @globalCTAS_PER_ROW, [avg(\@CTAS_PER_ROW)];
	
	@cta_diff_row = `grep "AVERAGE_CTA_ACCESS_DIFF_ROW" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@cta_diff_row);
	push @globalcta_diff_row, [avg(\@cta_diff_row)];
	
	@cta_diff_bank = `grep "AVERAGE_CTA_ACCESS_DIFF_BANK" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@cta_diff_bank);
	push @globalcta_diff_bank, [avg(\@cta_diff_bank)];
	
	@cta_diff_chip = `grep "AVERAGE_CTA_ACCESS_DIFF_CHIP" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@cta_diff_chip);
	push @globalcta_diff_chip, [avg(\@cta_diff_chip)];
		
	@cta_same_row = `grep "AVERAGE_CTA_ACCESS_SAME_ROW" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@cta_same_row);
	push @globalcta_same_row, [avg(\@cta_same_row)];
	
    @avg_cta_dist_2 = `grep "AVERAGE_CTA_DIST_2" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@avg_cta_dist_2);
	push @globalavg_cta_dist_2, [avg(\@avg_cta_dist_2)];
	
	@avg_cta_dist_3 = `grep "AVERAGE_CTA_DIST_3" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@avg_cta_dist_3);
	push @globalavg_cta_dist_3, [avg(\@avg_cta_dist_3)];
	
	@min_balance = `grep "min_balance" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@min_balance);
	push @globalmin_balance, [avg(\@min_balance)];

	@max_balance = `grep "max_balance" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@max_balance);
	push @globalmax_balance, [avg(\@max_balance)];
	
	@balance_ratio = `grep "CTA_BALANCE_RATIO" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@balance_ratio);
	push @globalbalance_ratio, [avg(\@balance_ratio)];		
	
	my $sum_1_32 = `grep "Sum1_32" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($sum_1_32);
	push @globalsum_1_32, $sum_1_32;
} 

  
    # BASELINE Starts ----------------------------------------------------------------
 	# General ----------------------------------
	print OUTPUT "Benchmarks \t";
	print OUTPUT "INS\t";
	
	# Warp Related -----------------------------
	print OUTPUT "Stall \t";
	print OUTPUT "W0Idle \t";
	print OUTPUT "W0Mem \t";
	
	# Latency Related
	print OUTPUT "DRAM-Queue \t";
	print OUTPUT "DRAM-Spent \t";
	print OUTPUT "Avg-fetch \t";
	print OUTPUT "latency1  \t";
	print OUTPUT "latency2  \t";

	# MISC 
	print OUTPUT "KERNELS \t";
	print OUTPUT "MAX_WARPS \t";
	print OUTPUT "CTAS_PER_ROW \t";
	print OUTPUT "CTA_DIFF_ROW \t";
	print OUTPUT "CTA_DIFF_CHIP \t";
	print OUTPUT "CTA_DIFF_BANK \t";
	print OUTPUT "CTA_SAME_ROW \t";
	print OUTPUT "CTA_DIST_2 \t";	
	print OUTPUT "CTA_DIST_3 \t";
	print OUTPUT "MIN_BAL \t";
	print OUTPUT "MAX_BAL \t";
	print OUTPUT "BAL_RATIO \t";
	print OUTPUT "SUM1-32 \t";
	# BASELINE Over ------------------------------
	
	print OUTPUT "\n";


for ($k = 0;$k <= $#file_list;$k++) 
{
    # BASELINE Starts ----------------------------------------------------------------
 	# General ----------------------------------
	print OUTPUT "$benchmarks[$k] \t";
	print OUTPUT "$globalins[$k] \t";
	
	# Warp Related -----------------------------
	print OUTPUT "$globalStall[$k] \t";
	print OUTPUT "$globalW0Idle[$k] \t";
	print OUTPUT "$globalW0Mem[$k] \t";
	
	# Latency Related -----------------------------
	print OUTPUT "$globaltotal_dram_queue[$k] \t";
	print OUTPUT "$globaltotal_dram_spent[$k] \t";
	print OUTPUT "$globalaveragemflatency[$k] \t";
	print OUTPUT "$globallatency1[$k] \t";
	print OUTPUT "$globallatency2[$k] \t";

	#MISC
	print OUTPUT "$globalkernels[$k] \t";
	print OUTPUT "$globalMAX_WARPS[$k][0] \t";
	print OUTPUT "$globalCTAS_PER_ROW[$k][0] \t";
	print OUTPUT "$globalcta_diff_row[$k][0] \t";
	print OUTPUT "$globalcta_diff_chip[$k][0] \t";
	print OUTPUT "$globalcta_diff_bank[$k][0] \t";
	print OUTPUT "$globalcta_same_row[$k][0] \t";
	print OUTPUT "$globalavg_cta_dist_2[$k][0] \t";
    print OUTPUT "$globalavg_cta_dist_3[$k][0] \t";
	print OUTPUT "$globalmin_balance[$k][0] \t";
	print OUTPUT "$globalmax_balance[$k][0] \t";
	print OUTPUT "$globalbalance_ratio[$k][0] \t";
	print OUTPUT "$globalsum_1_32[$k] \t";
	
	print OUTPUT "\n";
}


sub avg {
	@_ == 1 or die ('Sub usage: $avg = avg(\@array);');
	my ($array_ref) = @_;
	my $sum;
	my $count = scalar @$array_ref;
        if ($count == 0) {
                return 0;
        }
	foreach (@$array_ref) { $sum += $_; }
	return $sum / $count;
}

sub max {
	@_ == 1 or die ('Sub usage: $max = max(\@array);');
	my ($array_ref) = @_;
	my $maxval = -999999999999999999;
	foreach (@$array_ref)
	{
		if ( $maxval < $_ )
		{
			$maxval = $_;
		}
	}
	return $maxval;
}

sub sum {
	@_ == 1 or die ('Sub usage: $sum = sum(\@array);');
	my ($array_ref) = @_;
	my $sum;
	foreach (@$array_ref) { $sum += $_; }
	return $sum;
}


